/**
 *
 * @description CSS3 parser
 *
 * Grammar:
 *
 * JSON			-> Value '$'
 *
 * Value		-> 'string'
 * 				-> Object
 * 				-> Array
 * 				-> 'number'
 * 				-> 'date'
 * 				-> 'true'
 * 				-> 'false'
 * 				-> 'null'
 * 				-> 'undefined'
 * 				-> Function
 * 				-> '(' Value ')'
 *
 * Object		-> '{' '}'
 * 				-> '{' ObjectPairs '}'
 *
 * ObjectPairs	-> ObjectPairs ',' Name ':' Value
 * 				-> Name ':' Value
 *
 * Array		-> '[' ']'
 * 				-> '[' ArrayItems ']'
 *
 * ArrayItems	-> ArrayItems ',' Value
 * 				-> Value
 *
 * Name			-> 'string'
 * 				-> 'ident'
 *
 * Function		-> 'function' '(' ')' '{' '}'
 * 				-> 'function' '(' FuncParams ')' '{' '}'
 * 				-> 'function' '(' FuncParams ')' '{' FuncBlock '}'
 *
 * FuncParams	-> FuncParams ',' 'ident'
 * 				-> 'ident'
 *
 * FuncBlock	-> FuncBlock FuncBlockParenth
 * 				-> FuncBlock *
 * 				-> FuncBlockParenth
 * 				-> *
 *
 * FuncBlockParenth	-> '{' FuncBlock '}'
 * 					-> '{' '}'
 *
 *
 */

Jx.categorize('code.css.selector.parser', {

	$extend: 'Jx.lib.Parser',

	tokenizer: 'code.css.selector.tokenizer',

	ignoreProductions: [

		'whitespace',
		'singleline_comment',
		'multiline_comment'

	],


	states: {

		'start': {

			'Value': 'i1',
			'Object': 'reduceObject',
			'Array': 'reduceArray',
			'Function': 'reduceFunction',
			'date': 'reduceDate',
			'true': 'reduceBoolean',
			'false': 'reduceBoolean',
			'null': 'reduceNull',
			'undefined': 'reduceUndefined',
			'{': 'i2',
			'[': 'i7',
			'(': 'i10',
			'function': 'i12',
			'string': 'reduceString',
			'number': 'reduceNumber'

		},

		'i1': {
			'$': 'end'
		},

		//-- object start
		'i2': {
			'}': 'reduceObject',

			'ObjectPairs': 'i5',
			'Name': 'i3',
			'string': 'reduceString',
			'number': 'reduceNumber',
			'ident': 'reduceIdent'

		},

		'i3': {
			':': 'i4'
		},

		'i4': {
			'Value': 'reduceValue',
			'Object': 'reduceObject',
			'Array': 'reduceArray',
			'Function': 'reduceFunction',
			'date': 'reduceDate',
			'true': 'reduceBoolean',
			'false': 'reduceBoolean',
			'null': 'reduceNull',
			'undefined': 'reduceUndefined',
			'{': 'i2',
			'[': 'i7',
			'(': 'i10',
			'function': 'i12',
			'string': 'reduceString',
			'number': 'reduceNumber'
		},

		'i5': {
			',': 'i6',
			'}': 'reduceObject'
		},

		'i6': {
			'Name': 'i3',
			'string': 'reduceString',
			'number': 'reduceNumber',
			'ident': 'reduceIdent'
		},

		//-- array start
		'i7': {
			']': 'reduceEndArray',
			'ArrayItems': 'i8',
			'Value': 'reduceValue',
			'Object': 'reduceObject',
			'Array': 'reduceArray',
			'Function': 'reduceFunction',
			'date': 'reduceDate',
			'true': 'reduceBoolean',
			'false': 'reduceBoolean',
			'null': 'reduceNull',
			'undefined': 'reduceUndefined',
			'{': 'i2',
			'[': 'i7',
			'(': 'i10',
			'function': 'i12',
			'string': 'reduceString',
			'number': 'reduceNumber'
		},

		'i8': {
			',': 'i9',
			']': 'reduceEndArray'
		},

		'i9': {

			'Value': 'reduceValue',
			'Object': 'reduceObject',
			'Array': 'reduceArray',
			'Function': 'reduceFunction',
			'date': 'reduceDate',
			'true': 'reduceBoolean',
			'false': 'reduceBoolean',
			'null': 'reduceNull',
			'undefined': 'reduceUndefined',
			'{': 'i2',
			'[': 'i7',
			'(': 'i10',
			'function': 'i12',
			'string': 'reduceString',
			'number': 'reduceNumber'

		},

		//-- (Value) start
		'i10': {
			'Value': 'i11',
			'Object': 'reduceObject',
			'Array': 'reduceArray',
			'Function': 'reduceFunction',
			'date': 'reduceDate',
			'true': 'reduceBoolean',
			'false': 'reduceBoolean',
			'null': 'reduceNull',
			'undefined': 'reduceUndefined',
			'{': 'i2',
			'[': 'i7',
			'(': 'i10',
			'function': 'i12',
			'string': 'reduceString',
			'number': 'reduceNumber'
		},

		'i11': {
			')': 'reduceParenth'
		},

		//-- function start
		'i12': {
			'(': 'i13'
		},

		'i13': {
			')': 'i14',
			'FuncParams': 'i16',
			'ident': 'reduceIdent'
		},


		'i14': {
			'{': 'i15'
		},

		//-- function block
		'i15': {
			'FuncBlock': 'i18',
			'{': 'i19',
			'}': 'reduceEndFunction',
			'FuncBlockParenth': 'reduceFuncBlockParenth',

			'ident': 'reduceFuncBlockItem',
			'function': 'reduceFuncBlockItem',
			'string': 'reduceFuncBlockItem',
			'number': 'reduceFuncBlockItem',
			'true': 'reduceFuncBlockItem',
			'false': 'reduceFuncBlockItem',
			'null': 'reduceFuncBlockItem',
			'undefined':'reduceFuncBlockItem',
			'object': 'reduceFuncBlockItem',
			'date': 'reduceFuncBlockItem',

			'(': 'reduceFuncBlockItem',
			')': 'reduceFuncBlockItem',
			'[': 'reduceFuncBlockItem',
			']': 'reduceFuncBlockItem',

			':': 'reduceFuncBlockItem',
			',': 'reduceFuncBlockItem',
			'singleline_comment': 'reduceFuncBlockItem',
			'multiline_comment': 'reduceFuncBlockItem',
			'whitespace': 'reduceFuncBlockItem',

			'$garbage$': 'reduceFuncBlockItem'


		},

		//-- function params
		'i16': {
			',': 'i17',
			')': 'i14'
		},

		'i17': {
			'ident': 'reduceIdent'
		},

		//-- trail FuncBlock
		'i18': {
			'{': 'i19',
			'}': 'reduceEndFunction',
			'FuncBlockParenth': 'reduceFuncBlockParenth',

			'ident': 'reduceFuncBlockItem',
			'function': 'reduceFuncBlockItem',
			'string': 'reduceFuncBlockItem',
			'number': 'reduceFuncBlockItem',
			'true': 'reduceFuncBlockItem',
			'false': 'reduceFuncBlockItem',
			'null': 'reduceFuncBlockItem',
			'undefined':'reduceFuncBlockItem',
			'object': 'reduceFuncBlockItem',
			'date': 'reduceFuncBlockItem',

			'(': 'reduceFuncBlockItem',
			')': 'reduceFuncBlockItem',
			'[': 'reduceFuncBlockItem',
			']': 'reduceFuncBlockItem',

			':': 'reduceFuncBlockItem',
			',': 'reduceFuncBlockItem',
			'singleline_comment': 'reduceFuncBlockItem',
			'multiline_comment': 'reduceFuncBlockItem',
			'whitespace': 'reduceFuncBlockItem',

			'$garbage$': 'reduceFuncBlockItem'
		},


		//-- start FuncBlockParenth
		'i19': {
			'{': 'i19',
			'}': 'reduceFuncBlockParenthEnd',
			'FuncBlock': 'i20',

			'ident': 'reduceFuncBlockItem',
			'function': 'reduceFuncBlockItem',
			'string': 'reduceFuncBlockItem',
			'number': 'reduceFuncBlockItem',
			'true': 'reduceFuncBlockItem',
			'false': 'reduceFuncBlockItem',
			'null': 'reduceFuncBlockItem',
			'undefined':'reduceFuncBlockItem',
			'object': 'reduceFuncBlockItem',
			'date': 'reduceFuncBlockItem',

			'(': 'reduceFuncBlockItem',
			')': 'reduceFuncBlockItem',
			'[': 'reduceFuncBlockItem',
			']': 'reduceFuncBlockItem',

			':': 'reduceFuncBlockItem',
			',': 'reduceFuncBlockItem',
			'singleline_comment': 'reduceFuncBlockItem',
			'multiline_comment': 'reduceFuncBlockItem',
			'whitespace': 'reduceFuncBlockItem',

			'$garbage$': 'reduceFuncBlockItem'

		},

		'i20': {
			'{': 'i19',
			'}': 'reduceFuncBlockParenthEnd',
			'FuncBlockParenth': 'reduceFuncBlockItem',

			'ident': 'reduceFuncBlockItem',
			'function': 'reduceFuncBlockItem',
			'string': 'reduceFuncBlockItem',
			'number': 'reduceFuncBlockItem',
			'true': 'reduceFuncBlockItem',
			'false': 'reduceFuncBlockItem',
			'null': 'reduceFuncBlockItem',
			'undefined':'reduceFuncBlockItem',
			'object': 'reduceFuncBlockItem',
			'date': 'reduceFuncBlockItem',

			'(': 'reduceFuncBlockItem',
			')': 'reduceFuncBlockItem',
			'[': 'reduceFuncBlockItem',
			']': 'reduceFuncBlockItem',

			':': 'reduceFuncBlockItem',
			',': 'reduceFuncBlockItem',
			'singleline_comment': 'reduceFuncBlockItem',
			'multiline_comment': 'reduceFuncBlockItem',
			'whitespace': 'reduceFuncBlockItem',

			'$garbage$': 'reduceFuncBlockItem'
		},



		'reduceFuncBlockParenthEnd': {},
		'reduceFuncBlockEnd': {},
		'reduceFuncBlockItem': {},
		'reduceFunctionParams': {},
		'reduceEndFunction': {},
		'reduceFunction': {},
		'reduceBoolean': {},
		'reduceValue': {},
		'reduceString': {},
		'reduceNumber': {},
		'reduceObject': {},
		'reduceArray': {},
		'reduceDate': {},
		'reduceIdent': {},
		'reduceEndArray': {},
		'reduceParenth': {},


		'end': {}
	},

	anchors: [

		'start:i1:JSON',
		'start:i2:Object',
		'start:i7:Array',
		'start:i10:Value',
		'start:i12:Function',
		'start:reduceNull:Value',
		'start:reduceUndefined:Value',
		'start:reduceFunction:Value',
		'start:reduceBoolean:Value',
		'start:reduceString:Value',
		'start:reduceNumber:Value',
		'start:reduceDate:Value',
		'start:reduceObject:Value',
		'start:reduceArray:Value',

		'i2:i3:ObjectPairs',
		'i2:i5:ObjectPairs',
		'i2:reduceString:Name',
		'i2:reduceNumber:Name',
		'i2:reduceIdent:Name',

		'i4:i2:Object',
		'i4:i7:Array',
		'i4:i10:Value',
		'i4:i12:Function',
		'i4:reduceNull:Value',
		'i4:reduceUndefined:Value',
		'i4:reduceFunction:Value',
		'i4:reduceBoolean:Value',
		'i4:reduceString:Value',
		'i4:reduceNumber:Value',
		'i4:reduceDate:Value',
		'i4:reduceObject:Value',
		'i4:reduceArray:Value',


		'i6:reduceString:Name',
		'i6:reduceNumber:Name',
		'i6:reduceIdent:Name',

		'i7:i2:Object',
		'i7:i7:Array',
		'i7:i8:ArrayItems',
		'i7:i10:Value',
		'i7:i12:Function',
		'i7:reduceNull:Value',
		'i7:reduceUndefined:Value',
		'i7:reduceFunction:Value',
		'i7:reduceBoolean:Value',
		'i7:reduceString:Value',
		'i7:reduceNumber:Value',
		'i7:reduceDate:Value',
		'i7:reduceObject:Value',
		'i7:reduceArray:Value',
		'i7:reduceValue:ArrayItems',

		'i9:i2:Object',
		'i9:i7:Array',
		'i9:i10:Value',
		'i9:i12:Function',
		'i9:reduceNull:Value',
		'i9:reduceUndefined:Value',
		'i9:reduceFunction:Value',
		'i9:reduceBoolean:Value',
		'i9:reduceString:Value',
		'i9:reduceNumber:Value',
		'i9:reduceDate:Value',
		'i9:reduceObject:Value',
		'i9:reduceArray:Value',

		'i10:i2:Object',
		'i10:i7:Array',
		'i10:i10:Value',
		'i10:i12:Function',
		'i10:reduceNull:Value',
		'i10:reduceUndefined:Value',
		'i10:reduceFunction:Value',
		'i10:reduceBoolean:Value',
		'i10:reduceString:Value',
		'i10:reduceNumber:Value',
		'i10:reduceDate:Value',
		'i10:reduceObject:Value',
		'i10:reduceArray:Value',

		'i13:reduceIdent:FuncParams',
		'i13:i16:FuncParams',

		'i14:i15:FuncBlock',

		'i15:i18:FuncBlock',
		'i15:i19:FuncBlockParenth',
		'i15:reduceFuncBlockItem:FuncBlock',
		'i15:reduceFuncBlockParenth:FuncBlock',

		'i18:i19:FuncBlockParenth',
		'i18:reduceFuncBlockItem:FuncBlock',

		'i19:i19:FuncBlockParenth',
		'i19:i20:FuncBlock',
		'i19:reduceFuncBlockItem:FuncBlock',

		'i20:i19:FuncBlockParenth'

	],

	reduceStates: {

		'start': {
			'string': 'Value',
			'number': 'Value',
			'date': 'Value',
			'true': 'Value',
			'false': 'Value',
			'null': 'Value',
			'undefined':'Value',
			'Object': 'Value',
			'Array': 'Value',
			'Function': 'Value'

		},

		'i1': {
			'$': 'JSON'
		},

		'i2': {
			'}': 'Object',
			'string': 'Name',
			'number': 'Name',
			'ident': 'Name'
		},

		'i4': {
			'Value': 'ObjectPairs',
			'string': 'Value',
			'number': 'Value',
			'date': 'Value',
			'true': 'Value',
			'false': 'Value',
			'null': 'Value',
			'undefined':'Value',
			'Object': 'Value',
			'Array': 'Value',
			'Function': 'Value'
		},

		'i5': {
			'}': 'Object'
		},

		'i6': {
			'string': 'Name',
			'number': 'Name',
			'ident': 'Name'
		},

		'i7': {
			']': 'Array',
			'Value': 'ArrayItems',
			'string': 'Value',
			'number': 'Value',
			'date': 'Value',
			'true': 'Value',
			'false': 'Value',
			'null': 'Value',
			'undefined':'Value',
			'Object': 'Value',
			'Array': 'Value',
			'Function': 'Value'
		},

		'i8':{
			']': 'Array'
		},

		'i9': {
			'Value': 'ArrayItems',
			'string': 'Value',
			'number': 'Value',
			'date': 'Value',
			'true': 'Value',
			'false': 'Value',
			'null': 'Value',
			'undefined':'Value',
			'Object': 'Value',
			'Array': 'Value',
			'Function': 'Value'
		},

		'i10': {
			'string': 'Value',
			'number': 'Value',
			'date': 'Value',
			'true': 'Value',
			'false': 'Value',
			'null': 'Value',
			'undefined':'Value',
			'Object': 'Value',
			'Array': 'Value',
			'Function': 'Value'
		},

		'i11': {
			')': 'Value'
		},

		'i13': {
			'ident': 'FuncParams'
		},

		'i15': {
			'}': 'Function',
			'FuncBlockParenth': 'FuncBlock',

			'ident': 'FuncBlock',
			'function': 'FuncBlock',
			'string': 'FuncBlock',
			'number': 'FuncBlock',
			'true': 'FuncBlock',
			'false': 'FuncBlock',
			'null': 'FuncBlock',
			'undefined':'FuncBlock',
			'object': 'FuncBlock',
			'date': 'FuncBlock',

			'(': 'FuncBlock',
			')': 'FuncBlock',
			'[': 'FuncBlock',
			']': 'FuncBlock',

			':': 'FuncBlock',
			',': 'FuncBlock',
			'singleline_comment': 'FuncBlock',
			'multiline_comment': 'FuncBlock',
			'whitespace': 'FuncBlock',

			'$garbage$': 'FuncBlock'
		},

		'i17': {
			'ident': 'FuncParams'
		},

		'i18': {
			'}': 'Function',
			'FuncBlockParenth': 'FuncBlock',

			'ident': 'FuncBlock',
			'function': 'FuncBlock',
			'string': 'FuncBlock',
			'number': 'FuncBlock',
			'true': 'FuncBlock',
			'false': 'FuncBlock',
			'null': 'FuncBlock',
			'undefined':'FuncBlock',
			'object': 'FuncBlock',
			'date': 'FuncBlock',

			'(': 'FuncBlock',
			')': 'FuncBlock',
			'[': 'FuncBlock',
			']': 'FuncBlock',

			':': 'FuncBlock',
			',': 'FuncBlock',
			'singleline_comment': 'FuncBlock',
			'multiline_comment': 'FuncBlock',
			'whitespace': 'FuncBlock',

			'$garbage$': 'FuncBlock'
		},

		'i19': {
			'}': 'FuncBlockParenth',

			'ident': 'FuncBlock',
			'function': 'FuncBlock',
			'string': 'FuncBlock',
			'number': 'FuncBlock',
			'true': 'FuncBlock',
			'false': 'FuncBlock',
			'null': 'FuncBlock',
			'undefined':'FuncBlock',
			'object': 'FuncBlock',
			'date': 'FuncBlock',

			'(': 'FuncBlock',
			')': 'FuncBlock',
			'[': 'FuncBlock',
			']': 'FuncBlock',

			':': 'FuncBlock',
			',': 'FuncBlock',
			'singleline_comment': 'FuncBlock',
			'multiline_comment': 'FuncBlock',
			'whitespace': 'FuncBlock',

			'$garbage$': 'FuncBlock'

		},

		'i20': {
			'}': 'FuncBlockParenth',
			'FuncBlockParenth': 'FuncBlock',

			'ident': 'FuncBlock',
			'function': 'FuncBlock',
			'string': 'FuncBlock',
			'number': 'FuncBlock',
			'true': 'FuncBlock',
			'false': 'FuncBlock',
			'null': 'FuncBlock',
			'undefined':'FuncBlock',
			'object': 'FuncBlock',
			'date': 'FuncBlock',

			'(': 'FuncBlock',
			')': 'FuncBlock',
			'[': 'FuncBlock',
			']': 'FuncBlock',

			':': 'FuncBlock',
			',': 'FuncBlock',
			'singleline_comment': 'FuncBlock',
			'multiline_comment': 'FuncBlock',
			'whitespace': 'FuncBlock',

			'$garbage$': 'FuncBlock'

		}

	}

});
